﻿#region Using directives

using System;
using System.Collections.Generic;
using System.Text;

using Weazel.Badger.Vhdl;
using Weazel.Badger.Vhdl.Types;
using Weazel.Badger.Vhdl.Statements;

#endregion

namespace Weazel.Badger
{
  public class RegisterWriteSignal : RegisterSignal
  {
    public void Resolve(Entity entity, Process process, StatementCollection statements)
    {
      for(int i = 0; i < assignStatements.Count; i++)
      {
        SignalAssignmentStatement stmt = assignStatements[i];

        TypeSet possibleType = stmt.Expression.GetPossibleTypes();

        TypeConversionResult r = 
          TypeConverter.GetConversion(
            possibleType, 
            register.Type,
            stmt.Expression.GezelType,
            register.GezelType,       
            false          
          );

        if (r == null)
        {
          // no conversions possible
          string message =
            string.Format("no conversions exists from set {0} to type {1}",
              stmt.Expression.GetPossibleTypes(), 
              register.Type
            );

          throw new TypeResolveException(message);
        }

        // apply any conversions necessary
        assignStatements[i].Expression =
					ConversionBuilder.ApplyConversion(
						r, 
						(Vhdl.Statements.StatementCollection)stmt.Expression.ParentContainer,
						entity, 
						process,
						stmt.Expression
					);

        // finally, set the actual type of the driving expression
				stmt.Expression.SetActualType(entity, process, statements, register.Type);
      }
    }

    public override Weazel.Badger.Vhdl.Types.TypeSet GetPossibleTypes()
    {
      /*
      string message =
        "SetActualType() not supported for register read signals";

      throw new NotSupportedException(message);
      */

      return new Weazel.Badger.Vhdl.Types.TypeSet(register.Type);
    }

		public override void SetActualType(Entity entity, Process process, StatementCollection statements, Weazel.Badger.Vhdl.Types.Type type)
    {
      if ( !register.Type.Compare(type))
      {
        string message =
          "SetActualType(): Unusable type";

        throw new NotSupportedException(message);
      }
    }

    public RegisterWriteSignal(VhdlRegister register) : base(register, register.Name + "_wire")
    {
    }
  }
}
